package com.test.lol;

import android.app.*;
import android.content.*;
import android.database.*;
import android.location.*;
import android.media.*;
import android.net.*;
import android.os.*;
import android.provider.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import com.google.gson.*;
import java.io.*;
import org.apache.http.client.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.*;
import org.apache.http.impl.client.*;


public class ShareActivity extends Activity{
	
	private Uri uri;		// URI to photo
	private ProgressDialog pd;
	private DBResponseObject db;
	private String gpsJson;
	private LocationManager locationManager;
	private LocationListener locationListener;
	private String latitude;
	private String longitude;
	private byte [] data;
	private String captionStr;
	
	 public void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.share);
	        	        	        
	        // Gets the path to the photo from extra (uri)
	        Bundle extras = getIntent().getExtras();
	        uri = (Uri) extras.getParcelable("Uri");
      
	 }
	 	/*
	 	 * Method that fires when a user press "Send" button
	 	 * Creates a byte array from an image
	 	 * Extracts exif GPS data from an image
	 	 * Uses method sendData for uploading photo + information to server
	 	 */
	    public void onSend(View view){	    	
	    	
    		try{	
    					
				ContentResolver cr = getContentResolver();
				InputStream is = cr.openInputStream(uri);       			   			
				data = imageToBinary(is);
				is.close();   			
				            
	            EditText caption = (EditText) findViewById(R.id.caption); 
	            captionStr = ",'caption': '"+caption.getText()+"'}"; 
	            
	            gpsJson = this.getExif(uri);

	            //if there is gps exif data
	            if(gpsJson.length() > 20){
	                
	                gpsJson += captionStr;                
	                Log.v(this.getClass().getName(), "Send string: " + gpsJson);
	                
	            	pd = ProgressDialog.show(this, "Working..", "Uploading picture", true, false);
	            	Thread thread = new Thread(new SendData(Base64.encode(data, Base64.DEFAULT), gpsJson.getBytes(), this));
	                thread.start();
	            	
	            }else{
	            	// Displays an AlertDialog when no gps exif data could be found
	            	// Tries to get current gps location if user press "Yes"
	            	Log.e(this.getClass().getName(), "DEBUG 5");
	    	    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	    	    	builder.setMessage("Your photo does not contain any GPS data\nWould you like to use your current location?")
	    	    	       .setCancelable(false)
	    	    	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	    	    	           public void onClick(DialogInterface dialog, int id) {
	    	    	                getGPS(gpsJson, captionStr);
	    	    	           }
	    	    	       })
	    	    	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
	    	    	           public void onClick(DialogInterface dialog, int id) {
	    	    	                dialog.cancel();
	    	    	           }
	    	    	       });
	    	    	AlertDialog alert = builder.create();
	    	    	alert.show();
	            }
	
				}catch (Exception e){				
					Log.e(this.getClass().getName(), "Exception onSend: " + e.toString());
				}   		
	    }
	    
	    /*
	     * Gets current gps location and upload photo + gpsJson to server
	     */
	    public void getGPS(String extension, String caption){
        	// Acquire a reference to the system Location Manager
	    	this.gpsJson = extension;
	    	this.captionStr = caption;
        	locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        	// Define a listener that responds to location updates
        	locationListener = new LocationListener() {
        	    public void onLocationChanged(Location location) {
					// Called when a new location is found by the network location provider.
					latitude = Double.toString(location.getLatitude());
					longitude = Double.toString(location.getLongitude());
					locationManager.removeUpdates(locationListener);
					
					gpsJson += "'longitude':'"+longitude+"', 'latitude':'"+latitude+"'"+captionStr;
        	      
					pd = ProgressDialog.show(ShareActivity.this, "Working..", "Uploading picture", true, false);
					Thread thread = new Thread(new SendData(Base64.encode(data, Base64.DEFAULT), gpsJson.getBytes(), ShareActivity.this));
					thread.start();
        	    }

        	    public void onStatusChanged(String provider, int status, Bundle extras) {}

        	    public void onProviderEnabled(String provider) {}

        	    public void onProviderDisabled(String provider) {}
        	  };

        	// Register the listener with the Location Manager to receive location updates
        	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

	    }
	    
	    /*
	     * Close the activity when user press cancel button
	     */
	    public void onCancel(View view){
	    	this.finish();
	    }
	 
	    /*
	     * Method for extracting exif GPS data from an image
	     * After extraction it calls method convertGPSToDegree 
	     * @Param Uri - and uri to the image
	     * @Return json string that contains gps data
	     */
	    private String getExif(Uri uri){
	    	
	    	String exifFilePath;
	        String[] proj = { MediaStore.Images.Media.DATA };
	        String gpsJson;
	        String GPSToDegree;
	        
	        Cursor cursor = this.managedQuery(uri, proj, null, null, null);
	        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	        cursor.moveToFirst();
	        exifFilePath = cursor.getString(column_index);
	        int dotposition= exifFilePath.lastIndexOf(".");
	        String ext = exifFilePath.substring(dotposition + 1, exifFilePath.length());
	        
	    	try {
	    		ExifInterface exifInterface = new ExifInterface(exifFilePath);
	    		String longitude = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
	    		String latitude = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
	    		String longitudeRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
	    		String latitudeRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
	    		
	    		gpsJson = ",'extension': '"+ext+"',";
	    		GPSToDegree = convertGPSToDegree(longitude, longitudeRef, latitude, latitudeRef);
	    		
	    		if(GPSToDegree == "null"){
	    			return gpsJson;
	    			
	    		}else{
	    			gpsJson = gpsJson + GPSToDegree;
	    		}
	    						
			} catch (Exception e) {
				gpsJson = "ERROR";
				Log.e(this.getClass().getName(),"getExif: " + e.getMessage());
			}
	    	
	    	return gpsJson;
	    }
	    
	    /*
	     * Convert GPS photo data to Degree
	     * @Param longitude
	     * @Param longitudeRef
	     * @Param latitude
	     * @Param latitudeRef
	     * @Return string used with json
	     */
	    private String convertGPSToDegree(String longitude, String longitudeRef, String latitude, String latitudeRef){
	    		    	
	    	 if((latitude !=null)
	    	   && (latitudeRef !=null)
	    	   && (longitude != null)
	    	   && (longitudeRef !=null))
	    	 {

	    	  if(latitudeRef.equals("N")){
	    	   latitude = convertToDegree(latitude);
	    	  }
	    	  else{
	    	   latitude = "-"+convertToDegree(latitude);
	    	  }	    	 
	    	  if(longitudeRef.equals("E")){
	    	   longitude = convertToDegree(longitude);
	    	  }
	    	  else{
	    		  longitude = "-"+convertToDegree(longitude);
	    	  }    	 
	    	 }
	    	 
	    	 if(longitude == null || latitude == null){
	    		 return "null";
	    	 }
	    	 	    	 
	    	return "'longitude':'"+longitude+"', 'latitude':'"+latitude+"'";
	    }
	    
	    /*
	     * Same as method above but this does the calculation
	     * @Param stringDMS
	     * @Return result
	     */
	    private String convertToDegree(String stringDMS){
	    	
			 Float result = null;
			 String[] DMS = stringDMS.split(",", 3);
			
			 String[] stringD = DMS[0].split("/", 2);
			 Double D0 = new Double(stringD[0]);
			 Double D1 = new Double(stringD[1]);
			 Double FloatD = D0/D1;
			
			 String[] stringM = DMS[1].split("/", 2);
			 Double M0 = new Double(stringM[0]);
			 Double M1 = new Double(stringM[1]);
			 Double FloatM = M0/M1;
			  
			 String[] stringS = DMS[2].split("/", 2);
			 Double S0 = new Double(stringS[0]);
			 Double S1 = new Double(stringS[1]);
			 Double FloatS = S0/S1;
			  
			 result = new Float(FloatD + (FloatM/60) + (FloatS/3600));
			  
			 return result+"";
	    	}
	    
	    /*
	     * Converts an image to binary (byte array)
	     * @Param InputStream is
	     * @Return bytes
	     */
	    private byte[] imageToBinary(InputStream is){
	        
	        ByteArrayOutputStream bos = new ByteArrayOutputStream();
	        byte[] buf = new byte[1024];
	        
	        try {
	            for (int readNum; (readNum = is.read(buf)) != -1;) {
	                bos.write(buf, 0, readNum);
	            }
	        } catch (Exception ex) {
	        	Log.e(this.getClass().getName(), "ImageToBinary Exception: " + ex.getMessage());
	        }
	        
	        byte[] bytes = bos.toByteArray();
	        
	        return bytes;
	    }        
	    

	    
	    /*
	     * Uploads json string to server
	     * The string contains image as byte array, GPS data, Caption & name
	     * @Param data
	     * @Param sendDataString
	     */
		public class  SendData implements Runnable{

			private byte[] data;
			private byte[] sendDataString;
			private ShareActivity shareActivity;
	
			
			
			
			public SendData(byte[] data, byte[] sendDataString, ShareActivity shareActivity) {
				this.data = data;
				this.sendDataString = sendDataString;
				this.shareActivity = shareActivity;
			}
			
			public void run() {
			
		        try {
		            
		        	HttpClient client;
		        	HttpPost post;	
		        	BasicResponseHandler br = new BasicResponseHandler();
		        	String response;
	        			            
		        	post = new HttpPost(Common.baseUrl);	        		        	
		            byte [] sendArray = new byte[data.length+sendDataString.length+"{'img':''".length()];
		            
		            // Starting to build  the array for sending
		            // Json string
		            sendArray[0] = '{';
		            sendArray[1] = '\'';
		            sendArray[2] = 'i';
		            sendArray[3] = 'm';
		            sendArray[4] = 'g';
		            sendArray[5] = '\'';
		            sendArray[6] = ':';
		            sendArray[7] = '\'';
		            
		            int i = 8;
		            // Adds the image to sendArray
		            for(int j = 0; j < data.length; j++){            	
		            	sendArray[i] = data[j];
		            	i++;
		            }
		            
		            sendArray[i++] = '\'';
		            
		            // Adds gps data, caption & name to sendArray
		            for(int j = 0; j < sendDataString.length; j++){	            	
		            	sendArray[i] = sendDataString[j];
		            	i++;
		            }

		            ByteArrayEntity entity = new ByteArrayEntity(sendArray);
		            client = new DefaultHttpClient();
		            entity.setContentType("application/octet-stream");
		            post.setEntity(entity);	     
	            	response = client.execute(post, br); 	

	            	Log.v(this.getClass().getName(), "Response ShareActivity: "+response);
	            	            	
	            	Gson g = new Gson();	            	
	            	db = g.fromJson(response, DBResponseObject.class);
	            	
	            	pd.dismiss();
	            	handler.sendEmptyMessage(0); 	            	
	            	shareActivity.finish();
		            
		        } catch (Exception ex) {	   
		        	ex.printStackTrace();
		            Log.e(this.getClass().getName(), "sendData Excpetion: " + ex.toString());
		        }			      
			}	
	        private Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                	Toast.makeText(ShareActivity.this, " "+db.getMessage(), Toast.LENGTH_SHORT).show();    
                }
	        };
		}
	
}
